package org.aceor.mddal.common.sqlparser;

import com.google.common.base.Objects;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.aceor.mddal.common.sqlparser.result.SQLParsedResult;
import org.aceor.mddal.common.sqlparser.result.condition.ComparableUnit;
import org.aceor.mddal.common.sqlparser.result.context.ShardingContext;
import org.aceor.mddal.common.sqlparser.result.object.*;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * Created by lxue on 16/3/23.
 */
public class ParseContext {

    private SQLParsedResult sqlParsedResult = new SQLParsedResult();

    /**
     * 是否是select *
     * 用于Group by,Order by字段是否需要补列
     */
    private boolean hasAllColumn;

    /**
     * 分库分表字段
     */
    private Set<Column> shardingColumns = Sets.newHashSet();

    private Map<String, ShardingContext> tableShardingColumnsMapping = Maps.newHashMap();

    private Set<Column> selectColumns = Sets.newHashSet();

    public SQLParsedResult getSqlParsedResult() {
        return sqlParsedResult;
    }

    public void setSqlParsedResult(SQLParsedResult sqlParsedResult) {
        this.sqlParsedResult = sqlParsedResult;
    }

    public boolean isHasAllColumn() {
        return hasAllColumn;
    }

    public void setHasAllColumn(boolean hasAllColumn) {
        this.hasAllColumn = hasAllColumn;
    }

    public boolean isTableAlias(String tableOrAliasName) {
        return false;
    }

    public Set<Column> getShardingColumns() {
        return shardingColumns;
    }

    public void setShardingColumns(Set<Column> shardingColumns) {
        this.shardingColumns = shardingColumns;
    }

    public void addCondition(Column column, ComparableUnit unit) {
        getSqlParsedResult().conditionContext.addCondition(column, unit);
    }

    public void addShardingColumns(Collection<Column> columns) {
        shardingColumns.addAll(columns);
    }

    public void addShardingColumn(Column column) {
        shardingColumns.add(column);
    }

    public void addShardingColumn(String tableName, String columnName) {
        shardingColumns.add(new Column(new Table(tableName), columnName));
    }

    public void addSelectColumn(Column column) {
        selectColumns.add(column);
    }
    public void addOrderByColumn(OrderByColumn orderByColumn) {
        getSqlParsedResult().mergeContext.getOrderByColumns().add(orderByColumn);
    }

    public void addGroupByColumn(GroupByColumn column) {
        getSqlParsedResult().mergeContext.getGroupByColumns().add(column);
    }

    public void addAggregationColumn(AggregationColumn column) {
        getSqlParsedResult().mergeContext.getAggregationColumns().add(column);
    }

    public void addTable(Table table) {
        getSqlParsedResult().routeContext.getTables().add(table);
    }

    @Override
    public String toString() {
        return Objects.toStringHelper(this)
                .add("SQLParsedResult", sqlParsedResult)
                .toString();
    }

    public Column findSelectColumn(Column target) {
        for (Column column : selectColumns) {
            if (Objects.equal(column, Column.allColumn)) {
                return Column.allColumn;
            }
            if (Objects.equal(target.getName(), column.getName()) && Objects.equal(target.getTable(), column.getTable())) {
                return column;
            }
        }
        return null;
    }

    public Map<String, ShardingContext> getTableShardingColumnsMapping() {
        return tableShardingColumnsMapping;
    }

    public void setTableShardingColumnsMapping(Map<String, ShardingContext> tableShardingColumnsMapping) {
        this.tableShardingColumnsMapping = tableShardingColumnsMapping;
    }
}
